﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Data;
using System.Data.SqlClient;
using Lswweb.IDAL;
using Lswweb.Model;

namespace Lswweb.SqlServerDAL
{
    public class NewsDAL : INews
    {
        private Builder<NewsInfo> newsBuilder = new Builder<NewsInfo>("News","NewsId");
        private string _orderBy = "DisplayOrder asc,NewsId desc";

        public NewsDAL()
        {
            newsBuilder.GetParameters += new ParametersBuilder<NewsInfo>(GetParameters);
            newsBuilder.CreateModel += new ReaderBind<NewsInfo>(ReaderBind);
        }

        #region INews 成员

        public NewsInfo GetNews(int newsId)
        {
            return newsBuilder.GetModel(newsId);
        }

        public NewsInfo GetFirstNews(int categoryId,string language)
        {
            string where = "exists(select Id from NewsCategories where Ver=@Language and [path] + '/' like (select Path + '/' from NewsCategories AS NewsCategories_1 where (Id = @CategoryId)) + '%' AND (News.NewsCategoryId = Id))";

            return newsBuilder.GetModel(newsBuilder.TableName, string.Empty, where, _orderBy, DataAccess.CreateParameter("@CategoryId", categoryId), DataAccess.CreateParameter("@Language", language));
        }
         

        public NewsInfo GetNextNews(int newsId, int categoryId,string language)
        {
            string fields = "NewsId,Title,NewsCategoryId";
            string where = "NewsId<@NewsId and NewsCategoryId=@NewsCategoryId and Ver=@Language";
            IDataParameter[] parameters = new IDataParameter[]{
                DataAccess.CreateParameter("NewsId", newsId),
                DataAccess.CreateParameter("NewsCategoryId", categoryId),
                DataAccess.CreateParameter("@Language", language)};

            return newsBuilder.GetModel("News", fields, where, "DisplayOrder asc,NewsId desc", parameters);
        }

        public NewsInfo GetPrevNews(int newsId, int categoryId, string language)
        {
            string fields = "NewsId,Title,NewsCategoryId";
            string where = "NewsId>@NewsId and NewsCategoryId=@NewsCategoryId and Ver=@Language";
            IDataParameter[] parameters = new IDataParameter[]{
                DataAccess.CreateParameter("NewsId", newsId),
                DataAccess.CreateParameter("NewsCategoryId", categoryId),
                DataAccess.CreateParameter("@Language", language)};

            return newsBuilder.GetModel("News", fields, where, "DisplayOrder asc,NewsId asc", parameters);
        }

        public bool UpdateDisplayOrder(int newsId, int displayOrder)
        {
            if (newsId <= 0 || displayOrder<=0)
                return false;

            return newsBuilder.UpdateFields("DisplayOrder",newsId,displayOrder);
        }

        public IList<NewsInfo> GetNewsList(string searchKey, SearchKeyType searchKeyType, int categoryId, StatusType type,AuditingStatusType auditingStatus, BooleanType isHot, BooleanType isTop, DateTime maxDateTime, DateTime minDateTime, string ver, int pageIndex, int pageSize, out int totalRecord) 
        {
            StringBuilder where = new StringBuilder();
            IList<IDataParameter> list=new List<IDataParameter>();

            //SearchKey类别
            if (!string.IsNullOrEmpty(searchKey))
            {
                list.Add(DataAccess.CreateParameter("@SearchKey",searchKey));
                switch (searchKeyType)
                {
                    case SearchKeyType.Key :
                        where.Append(" and Keys like '%' + @SearchKey + '%'");
                        break;
                    case SearchKeyType.Promulgator :
                        where.Append(" and Promulgator=@SearchKey");
                        break;
                    case SearchKeyType.Title :
                    default:
                        where.Append(" and Title like '%' + @SearchKey + '%'");
                        break;
                }
            }

            //CategoryId条件
            if (categoryId > 0)
            {
                list.Add(DataAccess.CreateParameter("@CategoryId", categoryId));
                where.Append(" and exists(select Id from NewsCategories where [Path] + '/' like (select [Path] + '/' from NewsCategories AS NewsCategories_1 where (Id = @CategoryId)) + '%' AND (News.NewsCategoryId = Id))");
            }

            //Status条件
            if (Enum.IsDefined(typeof(StatusType), type))
            {
                list.Add(DataAccess.CreateParameter("@Status",type));

                where.Append(" and Status=@Status");
            }

            //AuditingStatus条件
            if(Enum.IsDefined(typeof(AuditingStatusType),auditingStatus))
            {
                list.Add(DataAccess.CreateParameter("@AuditingStatus", auditingStatus));

                where.Append(" and AuditingStatus=@AuditingStatus");
            }

            //IsTop条件
            if (isTop != BooleanType.None)
            {
                list.Add(DataAccess.CreateParameter("@IsTop", isTop));
                where.Append(" and IsTop=@IsTop");
            }
            
            //IsHot条件
            if (isHot != BooleanType.None)
            {
                list.Add(DataAccess.CreateParameter("@IsHot", isHot)); 
                where.Append(" and IsHot=@IsHot");
            }

            //maxDateTime条件
            if (maxDateTime != DateTime.MaxValue && maxDateTime!=DateTime.MinValue)
            {
                list.Add(DataAccess.CreateParameter("@MaxDateTime", maxDateTime));
                where.Append(" and DateCreated < @MaxDateTime");
            }

            //minDateTime条件
            if (minDateTime != DateTime.MinValue && minDateTime != DateTime.MaxValue)
            {
                list.Add(DataAccess.CreateParameter("@MinDateTime", minDateTime));
                where.Append(" and DateCreated > @MinDateTime");
            }

            if (!string.IsNullOrEmpty(ver))
            {
                list.Add(DataAccess.CreateParameter("Ver",ver));
                where.Append(" and Ver=@Ver");
            }

            return newsBuilder.GetModels(string.Empty, (where.Length>0)?where.ToString().Remove(0, 5):string.Empty, _orderBy, pageIndex, pageSize, out totalRecord, list.ToArray());
        }

        public int Insert(NewsInfo newsInfo)
        {
            return newsBuilder.Insert(
                newsInfo,
                "NewsCategoryId",
                "IsHot",
                "IsTop",
                "Title",
                "Keys",
                "Summary",
                "Source",
                "Promulgator",
                "ImageUrl",
                "Content",
                "Status",
                "AuditingStatus",
                "Ver",
                "DateCreated");
        }

        public bool Update(NewsInfo newsInfo)
        {
            if (newsInfo.NewsId <= 0)
                return false;

            return newsBuilder.Update(
                newsInfo,
                "NewsId=@NewsId",
                "NewsCategoryId",
                "Title",
                "Keys",
                "Summary",
                "Source",
                "Promulgator",
                "Content");
        }

        public bool UpdateIsTop(int newsId, bool isTop)
        {
            return newsBuilder.UpdateFields("IsTop", newsId, isTop);
        }

        public bool UpdateStatus(int newsId, StatusType type)
        {
            return newsBuilder.UpdateFields("Status", newsId, (int)type);
        }
        public bool UpdateStatus(int newsId, AuditingStatusType auditingStatus, string remark)
        {
            return newsBuilder.UpdateFields("AuditingStatus,Remark", newsId, (int)auditingStatus, remark);
        }

        public bool UpdateIsHot(int newsId, bool isHot)
        {
            return newsBuilder.UpdateFields("IsHot", newsId, isHot);
        }
        public bool UpdateCategory(int newsId, int categoryId)
        {
            if (categoryId < 0)
                return false;
            if (categoryId == 0)
                return newsBuilder.UpdateFields("NewsCategoryId", newsId, null);
            else
                return newsBuilder.UpdateFields("NewsCategoryId", newsId, categoryId);
        }

        public bool UpdateImageUrl(int newsId, string imageUrl)
        {
            if (newsId <= 0)
                return false;

            return newsBuilder.UpdateFields("ImageUrl",newsId,imageUrl);
        }

        public object GetFieldValue(int newsId,string fieldName)
        {
            if (newsId <= 0)
                return null;

            return newsBuilder.GetFieldValue(fieldName, newsId);
        }

        public bool Delete(int newsId)
        {
            return newsBuilder.Delete(newsId);
        }

        #endregion

        #region Protected Methods

        protected IDataParameter[] GetParameters(NewsInfo newsInfo)
        {
            return new IDataParameter[]{
                DataAccess.CreateParameter("@NewsId", newsInfo.NewsId),
                DataAccess.CreateParameter("@NewsCategoryId", newsInfo.NewsCategoryId),
                DataAccess.CreateParameter("@IsHot", newsInfo.IsHot),
                DataAccess.CreateParameter("@IsTop", newsInfo.IsTop),
                DataAccess.CreateParameter("@Title", newsInfo.Title),
                DataAccess.CreateParameter("@Keys", newsInfo.Keys),
                DataAccess.CreateParameter("@Summary", newsInfo.Summary),
                DataAccess.CreateParameter("@Source", newsInfo.Source),
                DataAccess.CreateParameter("@Promulgator", newsInfo.Promulgator),
                DataAccess.CreateParameter("@ImageUrl", newsInfo.ImageUrl),
                DataAccess.CreateParameter("@Content", newsInfo.Content),
                DataAccess.CreateParameter("@Status", (int)newsInfo.Status),
                DataAccess.CreateParameter("@AuditingStatus", newsInfo.AuditingStatus),
                DataAccess.CreateParameter("@Ver", newsInfo.Ver),
                DataAccess.CreateParameter("@DateCreated", newsInfo.DateCreated)
            };
        }

        protected NewsInfo ReaderBind(Hashtable dataReader)
        {
            NewsInfo model = new NewsInfo();

            if (dataReader.ContainsKey("NewsId"))
                model.NewsId = Convert.ToInt32(dataReader["NewsId"]);

            if (dataReader.ContainsKey("NewsCategoryId"))
                model.NewsCategoryId = Convert.ToInt32(dataReader["NewsCategoryId"]);

            if (dataReader.ContainsKey("IsHot"))
                model.IsHot = (bool)dataReader["IsHot"];

            if (dataReader.ContainsKey("IsTop"))
                model.IsTop = (bool)dataReader["IsTop"];

            if (dataReader.ContainsKey("DateCreated"))
                model.DateCreated = (DateTime)dataReader["DateCreated"];

            if (dataReader.ContainsKey("Title"))
                model.Title = dataReader["Title"].ToString();

            if (dataReader.ContainsKey("Keys"))
                model.Keys = dataReader["Keys"].ToString();

            if (dataReader.ContainsKey("Summary"))
                model.Summary = dataReader["Summary"].ToString();

            if (dataReader.ContainsKey("Source"))
                model.Source = dataReader["Source"].ToString();

            if (dataReader.ContainsKey("Promulgator"))
                model.Promulgator = dataReader["Promulgator"].ToString();

            if (dataReader.ContainsKey("ImageUrl"))
                model.ImageUrl = dataReader["ImageUrl"].ToString();

            if (dataReader.ContainsKey("Content"))
                model.Content = dataReader["Content"].ToString();

            if (dataReader.ContainsKey("Status"))
                model.Status = (StatusType)Convert.ToInt32(dataReader["Status"]);

            if (dataReader.ContainsKey("AuditingStatus"))
                model.AuditingStatus = (AuditingStatusType)Convert.ToInt32(dataReader["AuditingStatus"]);

            if (dataReader.ContainsKey("Ver"))
                model.Ver = dataReader["Ver"].ToString();

            if (dataReader.ContainsKey("DisplayOrder"))
                model.DisplayOrder = Convert.ToInt32(dataReader["DisplayOrder"]);

            return model;
        }

        #endregion
    }
}
